#include <48func.h>
typedef struct clientInfo_s {
    int isalive;
    int netfd;
    time_t lastactive;
} clientInfo_t;
int main(int argc, char *argv[])
{
    // ./1_server 192.168.118.128 1234
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);//ipv4 tcp
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(atoi(argv[2]));
    serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
    int reuseArg = 1;
    int ret = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&reuseArg,sizeof(reuseArg));
    ERROR_CHECK(ret,-1,"setsockopt");
    ret = bind(sockfd,(struct sockaddr *)&serverAddr,sizeof(serverAddr));
    ERROR_CHECK(ret,-1,"bind");
    ret = listen(sockfd,10);
    ERROR_CHECK(ret,-1,"listen");
    char buf[4096];
    int epfd = epoll_create(1);
    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = sockfd;
    epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&event);
    // 准备好数据结构 存储客户端的信息
    clientInfo_t client[1024];
    int curidx = 0;
    while(1){
        struct epoll_event readyset[1024];
        int readynum = epoll_wait(epfd,readyset,1024,1000);
        time_t curtime = time(NULL);
        printf("curtime = %s\n", ctime(&curtime));
        for(int j = 0; j < readynum; ++j){
            if(readyset[j].data.fd == sockfd){
                struct sockaddr_in clientAddr;
                socklen_t socklen = sizeof(clientAddr);//socklen必须初始化
                client[curidx].netfd = accept(sockfd,(struct sockaddr *)&clientAddr,&socklen);
                ERROR_CHECK(client[curidx].netfd,-1,"accept");
                printf("client ip = %s, port = %d\n",
                       inet_ntoa(clientAddr.sin_addr),
                       ntohs(clientAddr.sin_port));
                // 增加netfd
                client[curidx].isalive = 1; // 该客户端目前已经连接
                event.events = EPOLLIN;
                event.data.fd = client[curidx].netfd;
                epoll_ctl(epfd,EPOLL_CTL_ADD,client[curidx].netfd,&event);
                // 记录活跃时间
                client[curidx].lastactive = time(NULL);
                ++curidx;
            }
            else{
                for(int i = 0; i < curidx; ++i){
                    if(client[i].isalive != 0 && client[i].netfd == readyset[j].data.fd){
                        client[i].lastactive = time(NULL); // 记录活跃时间
                        bzero(buf,sizeof(buf));
                        ssize_t sret = recv(client[i].netfd,buf,sizeof(buf),0);
                        if(sret == 0){
                            epoll_ctl(epfd,EPOLL_CTL_DEL,client[i].netfd,NULL);
                            close(client[i].netfd);
                            client[i].isalive = 0;
                            break;
                        }
                        for(int k = 0; k < curidx; ++k){
                            if(k == i){
                                continue;
                            }
                            if(client[k].isalive != 0){
                                sret = send(client[k].netfd,buf,strlen(buf),0);
                                ERROR_CHECK(sret,-1,"send");
                            }
                        }
                    }
                }
            }   
        }
        for(int i = 0; i < curidx; ++i){
            if(client[i].isalive == 0){
                continue;
            }
            if(curtime - client[i].lastactive > 20){
                printf("close %d client!\n", i);
                epoll_ctl(epfd,EPOLL_CTL_DEL,client[i].netfd,NULL);
                close(client[i].netfd);
                client[i].isalive = 0;
            }
        }
    }
    return 0;
}



